package gov.pbc.nn.kjgl.maintenance.view;

import java.io.File;
import java.io.FileNotFoundException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.type.StandardBasicTypes;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.bstek.bdf2.core.business.IUser;
import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.bdf2.core.orm.ParseResult;
import com.bstek.bdf2.core.orm.hibernate.ISessionCallback;
import com.bstek.dorado.annotation.DataProvider;
import com.bstek.dorado.annotation.DataResolver;
import com.bstek.dorado.annotation.Expose;
import com.bstek.dorado.core.Configure;
import com.bstek.dorado.data.entity.EntityState;
import com.bstek.dorado.data.entity.EntityUtils;
import com.bstek.dorado.data.provider.Criteria;
import com.bstek.dorado.data.provider.Page;
import com.bstek.dorado.uploader.DownloadFile;
import com.bstek.dorado.uploader.UploadFile;
import com.bstek.dorado.uploader.annotation.FileProvider;
import com.bstek.dorado.uploader.annotation.FileResolver;
import com.bstek.dorado.uploader.widget.UploadAction;
import com.bstek.dorado.view.View;
import com.bstek.dorado.view.widget.Container;
import com.bstek.dorado.view.widget.action.AjaxAction;
import com.bstek.dorado.view.widget.base.Button;
import com.bstek.dorado.view.widget.base.tab.ControlTab;
import com.bstek.dorado.view.widget.form.FormElement;
import com.bstek.dorado.view.widget.form.autoform.AutoForm;
import com.bstek.dorado.web.DoradoContext;
import com.bstek.uflo.client.service.ProcessClient;
import com.bstek.uflo.client.service.TaskClient;
import com.bstek.uflo.model.task.Task;
import com.bstek.uflo.service.StartProcessInfo;

import gov.pbc.nn.core.dao.CommonHibernateDao;
import gov.pbc.nn.core.dao.CommonJdbcDao;
import gov.pbc.nn.core.dao.PbcnnCoreHibernateDao;
import gov.pbc.nn.core.utils.EntityRowMapperUtils;
import gov.pbc.nn.core.utils.GetTableUtils;
import gov.pbc.nn.core.utils.MapUtils;
import gov.pbc.nn.kjgl.maintenance.entity.SysChange;
import gov.pbc.nn.kjgl.maintenance.entity.SysMaterial;
import gov.pbc.nn.kjgl.maintenance.handler.SysCTOAssignmentHandler;
import gov.pbc.nn.uflo.UfloUtils;
import gov.pbc.nn.uflo.entity.Opinion;

@Component
public class SysChangePR {

	@Resource(name = CommonHibernateDao.BEAN_ID)
	private CommonHibernateDao hibernateDao;
	@Resource(name = CommonJdbcDao.BEAN_ID)
	private CommonJdbcDao jdbcDao;
	@Resource(name = PbcnnCoreHibernateDao.BEAN_ID)
	private PbcnnCoreHibernateDao coreHibernateDao;
	@Resource(name = ProcessClient.BEAN_ID)
	private ProcessClient pc;
	@Resource(name = TaskClient.BEAN_ID)
	private TaskClient tc;

	public void onInit(View view) {
		String viewName = view.getName();
		if ("gov.pbc.nn.kjgl.maintenance.view.SysChangeApply".equals(viewName)) {
			String taskId = ContextHolder.getRequest().getParameter("taskId");
			Task task = this.tc.getTask(Long.parseLong(taskId));
			String processName = this.pc.getProcessById(task.getProcessId()).getName();
			String nodeName = task.getNodeName();

			Button overBtn = (Button) view.getViewElement("overBtn");
			Button submitToBmfzrBtn = (Button) view.getViewElement("submitToBmfzrBtn");
			Button submitToYewuBtn = (Button) view.getViewElement("submitToYewuBtn");
			Button submitBtn = (Button) view.getViewElement("submitBtn");
			FormElement schemeFormElement = (FormElement) view.getViewElement("schemeFormElement");
			FormElement schemeNameFormElement = (FormElement) view.getViewElement("schemeNameFormElement");
			FormElement contentFormElement = (FormElement) view.getViewElement("contentFormElement");
			AutoForm changeForm = (AutoForm) view.getViewElement("changeForm");
			Button delSchemeFileBtn = (Button) view.getViewElement("delSchemeFileBtn");
			UploadAction uploadSchemeFileAction = (UploadAction) view.getViewElement("uploadSchemeFileAction");

			if (SysChangeNode.BusinessStartProcess.PROCESS_NAME.equals(processName)) {
				schemeFormElement.setVisible(SysChangeNode.BusinessStartProcess.NODE_7.equals(nodeName));
				schemeNameFormElement.setVisible(SysChangeNode.BusinessStartProcess.NODE_7.equals(nodeName));
				submitBtn.setVisible(SysChangeNode.BusinessStartProcess.NODE_7.equals(nodeName));
				submitToBmfzrBtn.setVisible(!SysChangeNode.BusinessStartProcess.NODE_7.equals(nodeName));
				contentFormElement.setVisible(SysChangeNode.BusinessStartProcess.NODE_7.equals(nodeName));
				overBtn.setVisible(false);
			} else {
				// 运维部门提出变更
				Object agreeObj = this.pc.getProcessVariable("agree", task.getProcessInstanceId());
				int agree = agreeObj == null ? -1 : Integer.parseInt(agreeObj.toString());
				schemeFormElement.setVisible(true);
				schemeNameFormElement.setVisible(true);
				submitBtn.setVisible(agree != 1);
				submitToBmfzrBtn.setVisible(false);
				submitToYewuBtn
						.setVisible(StringUtils.equals(
								String.valueOf(this.pc.getProcessVariable("agree", task.getProcessInstanceId())), "1")
								&& !StringUtils.equals(
										String.valueOf(this.pc.getProcessVariable("backFlow",
												task.getRootProcessInstanceId())), "-1"));
				changeForm.setReadOnly(agree == 1);
				delSchemeFileBtn.setDisabled(agree == 1);
				uploadSchemeFileAction.setDisabled(agree == 1);
				overBtn.setVisible(agree == 1);
			}

		} else if ("gov.pbc.nn.kjgl.maintenance.view.SysChangeAudit".equals(viewName)) {
			String taskId = ContextHolder.getRequest().getParameter("taskId");
			Task task = this.tc.getTask(Long.parseLong(taskId));
			String processName = this.pc.getProcessById(task.getProcessId()).getName();
			String nodeName = task.getNodeName();
			if (SysChangeNode.BusinessStartProcess.PROCESS_NAME.equals(processName)) {
				if (SysChangeNode.BusinessStartProcess.NODE_3.equals(nodeName)) {
					FormElement schemeFE = (FormElement) view.getViewElement("schemeFormElement");
					FormElement schemeNameFE = (FormElement) view.getViewElement("schemeNameFormElement");
					schemeFE.setVisible(false);
					schemeNameFE.setVisible(false);
				}
			}
		} else if ("gov.pbc.nn.kjgl.maintenance.view.SysChangeOpinion".equals(viewName)) {
			Container ctoContainer = (Container) view.getViewElement("ctoContainer");
			String taskId = ContextHolder.getRequest().getParameter("taskId");
			Task task = this.tc.getTask(Long.parseLong(taskId));
			String processName = this.pc.getProcessById(task.getProcessId()).getName();
			String nodeName = task.getNodeName();
			if (SysChangeNode.BusinessStartProcess.PROCESS_NAME.equals(processName)) {
				if (SysChangeNode.BusinessStartProcess.NODE_2.equals(nodeName)) {
					ctoContainer.setVisible(false);
					FormElement schemeFE = (FormElement) view.getViewElement("schemeFormElement");
					FormElement schemeNameFE = (FormElement) view.getViewElement("schemeNameFormElement");
					schemeFE.setVisible(false);
					schemeNameFE.setVisible(false);
				} else if (SysChangeNode.BusinessStartProcess.NODE_4.equals(nodeName)) {
					Object cto = this.pc.getProcessVariable("cto", task.getProcessInstanceId());
					ctoContainer.setVisible(cto == null);// 如果流程变量中已经有了cto的信息，则不再显示

					FormElement schemeFE = (FormElement) view.getViewElement("schemeFormElement");
					FormElement schemeNameFE = (FormElement) view.getViewElement("schemeNameFormElement");
					schemeFE.setVisible(false);
					schemeNameFE.setVisible(false);
				} else if (SysChangeNode.BusinessStartProcess.NODE_10.equals(nodeName)) {
					ctoContainer.setVisible(false);
				}
			} else {
				ctoContainer.setVisible(false);
			}

		} else if ("gov.pbc.nn.kjgl.maintenance.view.SysChangeOpinionAudit".equals(viewName)) {
			String caption = "";
			String taskId = ContextHolder.getRequest().getParameter("taskId");
			Task task = this.tc.getTask(Long.parseLong(taskId));
			String processName = this.pc.getProcessById(task.getProcessId()).getName();
			String nodeName = task.getNodeName();
			if (SysChangeNode.OperationStartProcess.PROCESS_NAME.equals(processName)) {
				if (SysChangeNode.OperationStartProcess.NODE_5.equals(nodeName)) {
					caption = "部门业务员意见";
					Button reGiveOpinionBtn = (Button) view.getViewElement("reGiveOpinionBtn");// 重新给出意见
					reGiveOpinionBtn.setVisible(true);
				}
			} else {
				Button reGiveOpinionBtn = (Button) view.getViewElement("reGiveOpinionBtn");// 重新给出意见
				Button noPassBtn = (Button) view.getViewElement("nopassBtn");// 不通过按钮

				if (SysChangeNode.BusinessStartProcess.NODE_5.equals(nodeName)) {
					caption = "运维人员意见";
					reGiveOpinionBtn.setVisible(true);
					noPassBtn.setVisible(false);

					FormElement schemeFE = (FormElement) view.getViewElement("schemeFormElement");
					FormElement schemeNameFE = (FormElement) view.getViewElement("schemeNameFormElement");
					schemeFE.setVisible(false);
					schemeNameFE.setVisible(false);
				} else if (SysChangeNode.BusinessStartProcess.NODE_6.equals(nodeName)) {
					caption = "运维人员意见";
					reGiveOpinionBtn.setVisible(true);
					noPassBtn.setVisible(true);

					FormElement schemeFE = (FormElement) view.getViewElement("schemeFormElement");
					FormElement schemeNameFE = (FormElement) view.getViewElement("schemeNameFormElement");
					schemeFE.setVisible(false);
					schemeNameFE.setVisible(false);
				} else if (SysChangeNode.BusinessStartProcess.NODE_11.equals(nodeName)) {
					caption = "部门业务员意见";
					reGiveOpinionBtn.setVisible(false);
					noPassBtn.setVisible(true);
				}
			}
			ControlTab opinionControlTab = (ControlTab) view.getViewElement("opinionControlTab");
			opinionControlTab.setCaption(caption);
		}

	}

	@DataProvider
	public void loadSysChanges(Page<SysChange> page, Criteria criteria) {
		int isBusinessStartProcess = Integer.parseInt(DoradoContext.getCurrent()
				.getAttribute(DoradoContext.VIEW, "isBusinessStartProcess").toString());
		// DetachedCriteria dc =
		// this.hibernateDao.buildDetachedCriteria(criteria, SysChange.class);
		// dc.add(Restrictions.eq("invalid", false));
		// dc.add(Restrictions.eq("deptId",
		// ContextHolder.getLoginUser().getDepts().get(0).getId()));
		// dc.add(Restrictions.eq("startByBusiness", isBusinessStartProcess ==
		// 1));
		// this.hibernateDao.pagingQuery(page, dc);

		String sql = "select c.*,m.FILE_NAME_ from t_sys_change c left join t_sys_material m on c.SCHEME_ID_=m.ID_ and m.INVALID_=0\n"
				+ "where c.INVALID_=0 and c.DEPT_ID_=:deptId and c.START_BY_BUSINESS_=:startByBusiness ";
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("deptId", ContextHolder.getLoginUser().getDepts().get(0).getId());
		params.put("startByBusiness", isBusinessStartProcess);
		if(!this.jdbcDao.containsProperty("state", criteria)){
			sql += "  and c.state_ in (0,5) ";
		}
		ParseResult result = this.jdbcDao.parseCriteria(criteria, true, "c");
		if (result != null) {
			sql += " and " + result.getAssemblySql();
			params.putAll(result.getValueMap());
		}
		sql += " order by c.create_date_";
		this.jdbcDao.pagingQuery(page, sql, new RowMapper<SysChange>() {

			@Override
			public SysChange mapRow(ResultSet rs, int rowNum) throws SQLException {
				try {
					SysChange change = EntityUtils.toEntity(EntityRowMapperUtils.get(SysChange.class, rs, rowNum));
					EntityUtils.setValue(change, "schemeName", rs.getString("FILE_NAME_"));
					return change;
				} catch (Exception e) {
					throw new RuntimeException(e);
				}
			}

		}, params);
	}

	@DataProvider
	public SysChange getSysChange(final String id) {
		final String sql = "select c.*,m.FILE_NAME_ as schemeName from t_sys_change c left join t_sys_material m on c.SCHEME_ID_=m.ID_ and m.INVALID_=0\n"
				+ "where c.ID_=?";
		return this.hibernateDao.doInHibernateSession(new ISessionCallback<SysChange>() {

			@Override
			public SysChange doInSession(Session session) {
				SQLQuery query = session.createSQLQuery(sql);
				query.setString(0, id);
				query.addEntity("c", SysChange.class);
				query.addScalar("schemeName", StandardBasicTypes.STRING);
				Object[] array = (Object[]) query.uniqueResult();
				SysChange change = null;
				try {
					change = EntityUtils.toEntity(array[0]);
					EntityUtils.setValue(change, "schemeName", array[1]);
				} catch (Exception e) {
					e.printStackTrace();
				}
				return change;
			}

		});

	}

	@DataResolver
	@Transactional
	public void saveSysChange(SysChange sysChange) throws Exception {
		EntityState state = EntityUtils.getState(sysChange);
		if (state == EntityState.NEW) {
			int isBusinessStartProcess = Integer.parseInt(DoradoContext.getCurrent()
					.getAttribute(DoradoContext.VIEW, "isBusinessStartProcess").toString());
			sysChange.setStartByBusiness(isBusinessStartProcess == 1);

			String tmpFilename = EntityUtils.getValue(sysChange, "tmpFilename");
			if (StringUtils.isNotBlank(tmpFilename)) {
				Path source = Paths.get(System.getProperty("java.io.tmpdir"), tmpFilename);
				Path path = Paths.get(Configure.getString("SYS_YUNWEI_FILE_UPLOAD_PATH"), "系统变更");
				if (!Files.exists(path)) {
					path = Files.createDirectories(path);
				}
				Path target = path.resolve(UUID.randomUUID().toString());

				SysMaterial material = new SysMaterial();
				material.setSysId(sysChange.getSysId());
				material.setSysName(sysChange.getSysName());
				material.setFileName((String) EntityUtils.getValue(sysChange, "schemeName"));
				material.setPath(target.toString());
				material.setType(8);// 文件类型：8，即系统变更
				this.hibernateDao.save(material);

				sysChange.setSchemeId(material.getId());
				this.hibernateDao.save(sysChange);

				Files.copy(source, target);
			} else {
				this.hibernateDao.save(sysChange);
			}
		} else {
			if (state == EntityState.MODIFIED) {
				this.hibernateDao.update(sysChange);
			}
		}
	}

	@FileResolver
	@Transactional
	public Map<String, Object> updateSchemeFile(UploadFile up, Map<String, Object> params) throws Exception {
		if (params == null)
			params = new HashMap<String, Object>();
		Map<String, Object> result = new HashMap<String, Object>();
		String changeId = (String) params.get("changeId");
		if (StringUtils.isEmpty(changeId)) {
			Path target = Files.createTempFile(null, null);
			Files.copy(up.getInputStream(), target, StandardCopyOption.REPLACE_EXISTING);
			result.put("tmpFilename", target.getFileName().toString());
		} else {
			Path path = Paths.get(Configure.getString("SYS_YUNWEI_FILE_UPLOAD_PATH"), "系统变更");
			if (!Files.exists(path)) {
				path = Files.createDirectories(path);
			}
			Path target = path.resolve(UUID.randomUUID().toString());

			SysChange change = this.hibernateDao.get(changeId, SysChange.class);
			this.deleteSchemeFile(MapUtils.newHashMap(new String[] { "changeId", "schemeId" }, new Object[] { changeId,
					change.getSchemeId() }));
			SysMaterial material = new SysMaterial();
			material.setSysId(change.getSysId());
			material.setSysName(change.getSysName());
			material.setFileName(up.getFileName());
			material.setPath(target.toString());
			material.setType(8);// 文件类型：8，即系统变更
			this.hibernateDao.save(material);

			change.setSchemeId(material.getId());
			this.hibernateDao.update(change);

			Files.copy(up.getInputStream(), target);

			result.put("schemeId", material.getId());
		}
		return result;
	}

	/**
	 * 删除方案文件
	 * 
	 * @param params
	 * @throws Exception
	 */
	@Expose
	@Transactional
	public void deleteSchemeFile(Map<String, Object> params) throws Exception {
		String schemeId = (String) params.get("schemeId");
		final String changeId = (String) params.get("changeId");
		if (StringUtils.isNotEmpty(schemeId)) {
			SysMaterial ma = (SysMaterial) this.hibernateDao.get(schemeId, SysMaterial.class);
			if (ma != null) {
				String path = ma.getPath();
				this.hibernateDao.delete(ma);

				final String hql = "update " + SysChange.class.getName() + " set schemeId=null where id=:changeId";
				this.hibernateDao.doInHibernateSession(new ISessionCallback<Void>() {

					@Override
					public Void doInSession(Session session) {
						session.createQuery(hql).setString("changeId", changeId).executeUpdate();
						return null;
					}

				});
				Files.deleteIfExists(Paths.get(path));
			}
		}

	}

	/**
	 * 下载方案文件
	 * 
	 * @param eventId
	 * @return
	 * @throws FileNotFoundException
	 */
	@FileProvider
	public DownloadFile downloadSchemeFile(Map<String, Object> params) throws FileNotFoundException {
		String schemeId = (String) params.get("schemeId");
		SysMaterial ma = (SysMaterial) this.hibernateDao.get(schemeId, SysMaterial.class);
		String path = ma.getPath();
		File file = new File(path);
		DownloadFile df = new DownloadFile(file);
		df.setFileName(ma.getFileName());
		return df;
	}

	/**
	 * 获取系统主管
	 * 
	 * @param sysId
	 * @return
	 */
	@DataProvider
	public List<Map<String, Object>> loadCTO(String sysId) {
		SysCTOAssignmentHandler handler = ContextHolder.getBean(SysCTOAssignmentHandler.BEAN_ID);
		List<IUser> list = handler.getCTO(sysId);
		List<Map<String, Object>> users = new ArrayList<Map<String, Object>>();
		for (IUser u : list) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("username", u.getUsername());
			map.put("cname", u.getCname());
			users.add(map);
		}
		return users;
	}

	@Expose
	@Transactional
	public void deleteChange(final String id) {
		String result = this.canDelete(id);
		if(result!=null){
			throw new UnsupportedOperationException(result);
		}
		this.hibernateDao.delete(id, SysChange.class);
		UfloUtils.deleteProcessInstance(id,true);
	}

	@Expose
	public String canDelete(String id) {
		SysChange sc = this.hibernateDao.get(id, SysChange.class);
		
		if (sc.getState()== 10 || sc.getState() == 20) {
			return "当前任务已经审批完成，不能删除！";
		}
		return null;
	}

	@Expose
	public String canModify(String id) {
		SysChange sc = this.hibernateDao.get(id, SysChange.class);
		if (sc.getState()== 5) {
			return "当前任务正在审批过程中，不能修改！";
		}
		if (sc.getState()== 10 || sc.getState() == 20) {
			return "当前任务已经审批完成，不能删除！";
		}
		return null;
	}

	@Expose
	public String canStartProcess(String id) {
		SysChange sc = this.hibernateDao.get(id, SysChange.class);
		if (sc.getState()== 5) {
			return "当前任务正在审批过程中，不能再次发起！";
		}
		if (sc.getState()== 10 || sc.getState() == 20) {
			return "当前任务已经审批完成，不能再次发起！";
		}
		return null;
	}

	/**
	 * 撤销流程
	 * 
	 * @param taskId
	 */
	@Expose
	@Transactional
	public void cancelProcess(String taskId) {
		Task task = this.tc.getTask(Long.parseLong(taskId));
		String businessId = task.getBusinessId();
		SysChange change = this.hibernateDao.get(businessId, SysChange.class);
		change.setState(20);// 撤销
		this.hibernateDao.update(change);

		Opinion o = new Opinion();
		o.setBusKey(businessId);
		o.setBusTable(GetTableUtils.getTablename(SysChange.class));
		o.setCname(ContextHolder.getLoginUser().getCname());
		o.setUsername(ContextHolder.getLoginUserName());
		o.setDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
		o.setDeptName(ContextHolder.getLoginUser().getDepts().get(0).getName());
		o.setOpinion("申请人撤销流程！");
		o.setProcessInstanceId(task.getProcessInstanceId());
		o.setProcessName(this.pc.getProcessById(task.getProcessId()).getName());
		o.setTaskId(task.getId());
		o.setTaskName(task.getTaskName());
		this.coreHibernateDao.save(o);

		// this.tc.forward(task.getId(), "结束");
		this.tc.start(task.getId());
		this.tc.complete(task.getId(), "to 结束");
	}

	/**
	 * 开启流程、驳回修改时完成任务
	 * 
	 * @param eventId
	 * @throws Exception
	 */
	@Transactional
	@DataResolver
	public void startProcess(SysChange sysChange, Map<String, Object> params) throws Exception {

		this.saveSysChange(sysChange);
		String taskId = (String) params.get("taskId");
		if (StringUtils.isEmpty(taskId)) {
			String result = this.canStartProcess(sysChange.getId());
			if(result!=null){
				throw new UnsupportedOperationException(result);
			}
			sysChange.setState(5);// 审核中
			sysChange.setDoDate(new Date());
			EntityState state = EntityUtils.getState(sysChange);
			if(state!=EntityState.NEW){
				EntityUtils.setState(sysChange, EntityState.MODIFIED);
			}
			this.saveSysChange(sysChange);

			boolean isBusinessStartProcess = Integer.parseInt(DoradoContext.getCurrent()
					.getAttribute(DoradoContext.VIEW, "isBusinessStartProcess").toString()) == 1;
			StartProcessInfo spi = new StartProcessInfo();
			spi.setBusinessId(sysChange.getId());
			spi.setCompleteStartTask(true);
			spi.setPromoter(ContextHolder.getLoginUserName());
			Map<String, Object> variables = new HashMap<String, Object>();
			variables.put("isBusinessStartProcess", isBusinessStartProcess);
			variables.put("sysId", sysChange.getSysId());
			variables.put("sysName", sysChange.getSysName());
			// variables.put("agree", 1);//2017-03-29
			spi.setVariables(variables);
			if (!isBusinessStartProcess) {
				// 运维部门提出变更
				variables.put("cto", params.get("cto").toString());
				variables.put("taskname", "运维部门申请【" + sysChange.getSysName() + "】变更，请技术主管审核");
				this.pc.startProcessByName(SysChangeNode.OperationStartProcess.PROCESS_NAME, spi);
			} else {
				// 业务部门提出变更
				variables.put("ywyjDone", false);
				variables.put("ywyj", Integer.parseInt(params.get("ywyj").toString()) == 1);
				String businessDeptLeader = (String) params.get("businessDeptLeader");
				if (StringUtils.isNoneBlank(businessDeptLeader) && Integer.parseInt(params.get("ywyj").toString()) == 0) {
					variables.put("businessDeptLeader", businessDeptLeader);
				}
				this.pc.startProcessByName(SysChangeNode.BusinessStartProcess.PROCESS_NAME, spi);
			}
		} else {
			this.saveSysChange(sysChange);
			Task task = this.tc.getTask(Long.parseLong(taskId));
			Map<String, Object> variables = new HashMap<String, Object>();
			boolean isBusinessStartProcess = (boolean) this.pc.getProcessVariable("isBusinessStartProcess",
					task.getProcessInstanceId());
			if (!isBusinessStartProcess) {
				// 运维部门提出变更
				variables.put("cto", params.get("cto").toString());
				variables.put("taskname", "运维部门申请【" + sysChange.getSysName() + "】变更，请技术主管审核");
			} else {
				// 业务部门提出变更
				variables.put("ywyjDone", true);// 表示运维意见意见给出
				String businessDeptLeader = (String) params.get("businessDeptLeader");
				if (StringUtils.isNoneBlank(businessDeptLeader)) {
					variables.put("businessDeptLeader", businessDeptLeader);
				}
				Object jszgsh = params.get("jszgsh");
				if (jszgsh != null) {
					variables.put("jszgsh", jszgsh);// 运维人员制定方案，是否需要技术主管审核.
				}
			}
			variables.put("agree", 1);
			this.tc.start(Long.parseLong(taskId));
			this.tc.complete(Long.parseLong(taskId), variables);
		}
	}

	/**
	 * 提交到业务主管部门
	 * 
	 * @param params
	 */
	@Expose
	@Transactional
	public void toYewuDept(Map<String, Object> params) {
		long taskId = Long.parseLong(params.get("taskId").toString());
		String opinion = (String) params.get("opinion");

		Task task = this.tc.getTask(taskId);
		String processName = this.pc.getProcessById(task.getProcessId()).getName();
		String target = null;
		if (processName.equals(SysChangeNode.OperationStartProcess.PROCESS_NAME)) {
			target = SysChangeNode.OperationStartProcess.NODE_4;
		} else {
			throw new UnsupportedOperationException();
		}
		Opinion o = new Opinion();
		o.setBusKey(task.getBusinessId());
		o.setBusTable(GetTableUtils.getTablename(SysChange.class));
		o.setOpinion(opinion);
		o.setProcessInstanceId(task.getProcessInstanceId());
		o.setProcessName(processName);
		o.setTaskId(taskId);
		o.setTaskName(task.getTaskName());
		o.setNodeName(task.getNodeName());
		o.setUsername(ContextHolder.getLoginUserName());
		o.setCname(ContextHolder.getLoginUser().getCname());
		o.setDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
		o.setDeptName(ContextHolder.getLoginUser().getDepts().get(0).getName());
		this.coreHibernateDao.save(o);
		Map<String, Object> variables = new HashMap<String, Object>();
		SysChange sysChange = this.getSysChange(task.getBusinessId());
		variables.put("taskname", "运维部门申请【" + sysChange.getSysName() + "】变更，请业务员填写意见");
		this.tc.forward(taskId, target, variables);
	}

	/**
	 * 直接结束
	 * 
	 * @param params
	 */
	@Expose
	@Transactional
	public void processOver(Map<String, Object> params) {
		long taskId = Long.parseLong(params.get("taskId").toString());
		String opinion = (String) params.get("opinion");

		Task task = this.tc.getTask(taskId);
		String processName = this.pc.getProcessById(task.getProcessId()).getName();

		Opinion o = new Opinion();
		o.setBusKey(task.getBusinessId());
		o.setBusTable(GetTableUtils.getTablename(SysChange.class));
		o.setOpinion(opinion);
		o.setProcessInstanceId(task.getProcessInstanceId());
		o.setProcessName(processName);
		o.setTaskId(taskId);
		o.setTaskName(task.getTaskName());
		o.setNodeName(task.getNodeName());
		o.setUsername(ContextHolder.getLoginUserName());
		o.setCname(ContextHolder.getLoginUser().getCname());
		o.setDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
		o.setDeptName(ContextHolder.getLoginUser().getDepts().get(0).getName());
		this.coreHibernateDao.save(o);

		// this.tc.forward(taskId, "结束");
		this.tc.start(task.getId());
		this.tc.complete(task.getId(), "to 结束");
	}

	public static class SysChangeNode {
		public static class BusinessStartProcess {

			public static final String PROCESS_NAME = "业务部门提出系统变更";
			/**
			 * 申请系统变更
			 */
			public static final String NODE_1 = "申请系统变更";
			/**
			 * 运维人员意见1
			 */
			public static final String NODE_2 = "运维人员意见1";
			/**
			 * 业务主管部门负责人审核
			 */
			public static final String NODE_3 = "业务主管部门负责人审核";
			/**
			 * 运维人员意见2
			 */
			public static final String NODE_4 = "运维人员意见2";
			/**
			 * 系统技术主管审核变更意见
			 */
			public static final String NODE_5 = "系统技术主管审核变更意见";
			/**
			 * 运维部门主管审核变更意见
			 */
			public static final String NODE_6 = "运维部门主管审核变更意见";
			/**
			 * 运维人员制定方案
			 */
			public static final String NODE_7 = "运维人员制定方案";
			/**
			 * 系统技术主管审核变更计划
			 */
			public static final String NODE_8 = "系统技术主管审核变更计划";
			/**
			 * 运维部门主管审核变更计划
			 */
			public static final String NODE_9 = "运维部门主管审核变更计划";
			/**
			 * 业务部门业务员填写意见
			 */
			public static final String NODE_10 = "业务部门业务员填写意见";
			/**
			 * 业务主管部门负责人审核方案
			 */
			public static final String NODE_11 = "业务主管部门负责人审核方案";
		}

		public static class OperationStartProcess {

			public static final String PROCESS_NAME = "运维部门提出系统变更";
			/**
			 * 申请系统变更
			 */
			public static final String NODE_1 = "申请系统变更";
			/**
			 * 系统技术主管审核
			 */
			public static final String NODE_2 = "系统技术主管审核";
			/**
			 * 运维部门主管审核
			 */
			public static final String NODE_3 = "运维部门主管审核";
			/**
			 * 业务主管部门业务员意见
			 */
			public static final String NODE_4 = "业务主管部门业务员意见";
			/**
			 * 业务主管部门负责人审核
			 */
			public static final String NODE_5 = "业务主管部门负责人审核";
		}
	}
}
